﻿using System;
using Loki.Utils;
using NUnit.Framework;

namespace Loki.Core.Test.Events
{
    public class EventsTests : AssertionHelper
    {
        [Test]
        public void ShouldHandleEventWhenBothReferencesAreAlive()
        {
            var L_Observed = new DummyObserved();
            var L_Observer = new DummyObserver(L_Observed);
            L_Observed.Property = "Value1";
            L_Observed.Property = "Value2";

            Assert.AreEqual(2, L_Observer.Count);
        }

        [Test]
        public void ShouldAllowSubscriberReferenceToBeCollected()
        {
            var L_Observed = new DummyObserved();
            var L_ObserverReference = null as WeakReference;
            new Action(() =>
            {
                // Run this in a delegate to that the local variable gets garbage collected
                var L_Observer = new DummyObserver(L_Observed);
                L_Observed.Property = "Value1";
                L_Observed.Property = "Value2";

                Assert.AreEqual(2, L_Observer.Count);
                L_ObserverReference = new WeakReference(L_Observer);
            })();

            GC.Collect();
            LokiServices.Event.RemoveCollectedEntries();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Assert.IsNull(L_ObserverReference.Target);
        }

        [Test]
        public void ShouldAllowSynchronizeReferenceToBeCollected()
        {
            var L_LongLife = new LokiCollection<DummyObserved>();
            var L_ObserverReference = null as WeakReference;
            new Action(() =>
            {
                var L_Observer = new LokiCollection<DummyObserved>();
                L_Observer.Synchronize(L_LongLife, (o, n) => { n.Property = o.Property; }, (o, n) => o.Property == n.Property, o => o.Property);
                L_LongLife.Add(new DummyObserved() { Property = "value1" });
                L_LongLife.Add(new DummyObserved() { Property = "value2" });

                Expect(L_Observer.Count, Is.EqualTo(2));
                L_ObserverReference = new WeakReference(L_Observer);
            })();


            GC.Collect();
            LokiServices.Event.RemoveCollectedEntries();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Assert.IsNull(L_ObserverReference.Target);
        }
    }
}
